import os
import zipfile


class Zip_Manager:
    def __init__(self, zip_filename):
        """
        压缩包类,初始化时指定压缩包的名称 \n

        :param zip_filename: 压缩包名称 \n
        """
        # 初始化时指定压缩包的名称
        self.zip_filename = zip_filename
        self.zip_obj = None

    def compress_files(self, file_list: list):
        """
        将指定列表中的文件压缩成一个压缩包 \n

        :param file_list: 文件路径 \n
        :return: 布尔值 \n
        """
        orgin_path = os.getcwd()

        try:
            with zipfile.ZipFile(self.zip_filename, mode='w') as archive:
                for file in file_list:
                    if os.path.isfile(file) and os.path.exists(file):
                        if os.path.split(file)[0] != '':
                            os.chdir(os.path.split(file)[0])
                        archive.write(os.path.split(file)[1])

                    os.chdir(orgin_path)
            os.chdir(orgin_path)
            return True
        except Exception as e:
            print(e)
            return False

    def compress_dir(self, directory):
        """
        将指定目录压缩成一个压缩包 \n

        :param directory: 要压缩的目录 \n
        :return: 布尔值 \n
        """
        if os.path.exists(directory) and os.path.isdir(directory):
            with zipfile.ZipFile(self.zip_filename, 'w', zipfile.ZIP_DEFLATED) as zf:
                for root, dirs, files in os.walk(directory):
                    for file in files:
                        zf.write(os.path.join(root, file), os.path.relpath(os.path.join(root, file), directory))
            print(f"压缩包 '{self.zip_filename}' 已创建。")
            return True
        else:
            return False

    def extract_all(self, extract_dir):
        """
        解压压缩包 \n

        :param extract_dir: 解压到哪个文件夹，文件夹可以不存在 \n
        :return: 布尔值 \n
        """
        # if os.path.exists(extract_dir):
        try:
            with zipfile.ZipFile(self.zip_filename, 'r') as zf:
                zf.extractall(extract_dir)
            print(f"压缩包 '{self.zip_filename}' 已解压到 '{extract_dir}'。")
            return True
        except Exception as e:
            print(e)
            return False

    def add_file(self, file_to_add, is_compare_path=True):
        """
        添加单独的文件到压缩包 \n

        :param file_to_add: 文件路径 \n
        :param is_compare_path: 是否和本地路径相同 \n
        :return: 布尔值 \n
        """
        if os.path.exists(file_to_add) and os.path.isfile(file_to_add):
            with zipfile.ZipFile(self.zip_filename, 'a') as zf:
                if is_compare_path:
                    zf.write(file_to_add)
                else:
                    base_name = os.path.basename(file_to_add)
                    # 处理文件在压缩包内已存在的情况
                    if base_name in [info.filename for info in zf.infolist()]:
                        print(f"文件 '{base_name}' 已存在于压缩包中，不重复添加。")
                        return False
                    zf.write(file_to_add, arcname=base_name)
            print(f"文件 '{file_to_add}' 已添加到压缩包 '{self.zip_filename}'。")
            return True
        else:
            return False

    def rename_zip(self, new_name):
        """
        修改压缩包名 \n

        :param new_name: 新名称 \n
        :return: 布尔值 \n
        """
        # 检查压缩包是否存在
        if os.path.exists(self.zip_filename):
            # 重命名压缩包
            os.rename(self.zip_filename, new_name)
            self.zip_filename = new_name
            print(f"压缩包名已改为 '{new_name}'。")
            return True
        else:
            print(f"压缩包 '{self.zip_filename}' 不存在，无法重命名。")
            return False

    def delete_zip(self):
        """
        删除压缩包 \n

        :return: 布尔值 \n
        """
        # 检查压缩包是否存在
        if os.path.exists(self.zip_filename):
            # 删除压缩包
            os.remove(self.zip_filename)
            print(f"压缩包 '{self.zip_filename}' 已被删除。")
            return True
        else:
            print(f"压缩包 '{self.zip_filename}' 不存在，无需删除。")
            return False

    def list_contents(self):
        """
        查看压缩包里面的文件和目录 \n

        :return: \n
        """
        try:
            wb = []
            with zipfile.ZipFile(self.zip_filename, 'r') as zf:
                for info in zf.infolist():
                    # print(info.filename)
                    wb.append(info.filename)
                return wb

        except Exception as e:
            print(e)
            return False
